#include "Timer.h"

class TimerPrivateData
{
public:
    uv_loop_t *loop;
    uv_timer_t *timer;
    Timer::OnTimer onTimer;
    void *userData;
    uint64_t timeout;
    uint64_t repeat;
};

Timer::Timer()
{
    data = std::unique_ptr<TimerPrivateData>(new TimerPrivateData());
    data->loop = uv_default_loop();
    data->timer = static_cast<uv_timer_t *>(malloc(sizeof(uv_timer_t)));
    uv_timer_init(data->loop, data->timer);
}

Timer::~Timer()
{
    free(data->timer);
}

void Timer::timerCB(uv_timer_t *handle)
{
    auto *thisPointer = static_cast<Timer *>(handle->data);
    if (thisPointer->data->onTimer != nullptr)
    {
        thisPointer->data->onTimer(thisPointer->data->userData);
    }
}

void Timer::start(uint64_t timeout, uint64_t repeat)
{
    data->timer->data = (void *)this;
    data->timeout = timeout;
    data->repeat = repeat;
    uv_timer_start(data->timer, Timer::timerCB, timeout, repeat);
}

void Timer::setTimerCallback(OnTimer onTimer, void *userData)
{
    data->onTimer = onTimer;
    data->userData = userData;
}

void Timer::stop()
{
    uv_timer_stop(data->timer);
}
